import axios, { AxiosResponse } from "axios";
import nProgress from "nprogress";
import "nprogress/nprogress.css"; //引入nprogress的动画效果的css文件
import actionToken from "../tools/actionToken";
import { xmlyResData, SggResData } from "@/type/resType/resType";//引入需要服务器返回的数据的类型的文件
import { OPTIONS } from "@/type/paramsType/parmsType";//引入杂七杂八类型的文件
import baseUrlObj from "@/tools/baseUrl";//引入配置的发请求的基本路径对象
import useUserStore from "@/store/user";


/**
* @author王华贵
* @Description :类封装axios站点,用于发请求
*/
class Request {
    // 封装使用axios对象式调用 //private：该修饰符修饰的方法只能在基类中使用
    private api<T>(options: OPTIONS, key: string) {
        // 创建站点
        const service = axios.create({
            baseURL: baseUrlObj[key],
            timeout: 50000,
            timeoutErrorMessage: "请求超时！"
        })
        // 请求拦截器
        service.interceptors.request.use((config) => {
            nProgress.start();// 开启加载效果
            // 若存在token就携带token
            let token = actionToken.getToken();
            token && (config.headers["token"] = token);
            config.headers["Content-Type"] = "application/json";//json格式的返回数据
            return config
        }, (error) => {
            return error
        });
        // 响应拦截器：// 
        service.interceptors.response.use((response: AxiosResponse<any, xmlyResData<T> | SggResData<T>>) => {
            // 简化数据
            let res = response.data;
            //关闭加载效果
            nProgress.done();
            // 说明此时是在请求喜马拉雅的服务器
            if (key === "xmly" || key === "search") return res;
            // 对尚硅谷服务器的响应和喜马拉雅服务器的响应做判定
            if (res.code === 200) {
                return res.data;
            } else if (res.code === 208 || res.code === 20001) {
                useUserStore().logoutHandler();//清空token和用户信息数据
                console.log("响应拦截器中：res.code === 20001");
                return Promise.reject(res.data);//失败链式下穿
            } else {
                return Promise.reject(res.data);
            }
        }, (error) => {
            nProgress.done();//关闭加载效果
            return Promise.reject(error.response.statusText || "网络波动异常");
        });
        return service<any, T>(options);
    }

    // protected 该修饰符只针对于typescript版本中对于class：该修饰符修饰的方法只能在基类和派生类中使用
    protected get<T>(options: OPTIONS, key = "xmly") {
        options.method = "GET";
        return this.api<T>(options, key)
    }
    protected post<T>(options: OPTIONS, key = "xmly") {
        options.method = "POST";
        return this.api<T>(options, key)
    }
    protected put<T>(options: OPTIONS, key = "xmly") {
        options.method = "PUT";
        return this.api<T>(options, key)
    }
    protected delete<T>(options: OPTIONS, key = "xmly") {
        options.method = "DELETE";
        return this.api<T>(options, key)
    }
}
export default Request;